只要有應用必定有黑帽駭客的出現,要做好防範黑客的機制在現今已經是標配,雖然不見得是資安大師,但至少要把最基本的防禦做好,善盡工程師的責任!Express 官方在安全最佳作法中有提及到應該使用 helmet 套件來防範應用程式出現已知的漏洞,那 helmet 到底能做到什麼事情呢?
helmet 是由多個中介軟體所構成,它做的事情很簡單,就是 修改 header 中的資訊 ,來做到一些基本的防護,降低被黑客攻擊的風險。安裝方式一樣透過 npm 進行:
npm install helmet
要使用的話也是很簡單,並且 helmet 很自由,可以使用 我全都要 模式,來打開所有 helmet 中介軟體的功能:
import helmet from 'helmet';
app.use(helmet());
這樣就可以把所有配置都打開了,但根本不知道它做了啥呀!也不確定是不是每項都是需要的,還有就是能否只使用某幾個或是哪些不使用呢?下方會進行個別說明。
本篇章的重點為如何使用 helmet 套件,但內容涉及眾多 header 知識,為了不失焦,所以僅會說明該功能的用處並附上相關知識連結,敬請見諒!
透過設置 Content-Security-Policy
來降低跨網域腳本攻擊,可以參考 MDN 的說明文件 來了解有哪些參數可以設置。下方為使用 helmet 提供的方法來設置的範例:
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "example.com"],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
})
);
當然,也可以不設置任何參數直接使用 helmet.contentSecurityPolicy()
,那就會採用下方預設值:
default-src 'self';
base-uri 'self';
block-all-mixed-content;
font-src 'self' https: data:;
frame-ancestors 'self';
img-src 'self' data:;
object-src 'none';
script-src 'self';
script-src-attr 'none';
style-src 'self' https: 'unsafe-inline';
upgrade-insecure-requests
透過設置 Expect-CT
來降低憑證發行錯誤,可以參考 MDN 的說明文件 來了解各個參數的意義。下方為使用 helmet 提供的方法來設置的範例:
app.use(
helmet.expectCt({
maxAge: 86400,
enforce: true,
reportUri: "https://example.com/report",
})
);
參數預設值:
maxAge
:預設為 0
enforce
:預設為 false
reportUri
:無預設配置透過設置 Referrer-Policy
來控管 Referrer 的資訊,可以參考 MDN 的說明文件 來了解各參數的意義。下方為使用 helmet 提供的方法來設置的範例:
app.use(
helmet.referrerPolicy({
policy: ["origin", "unsafe-url"],
})
);
policy
參數預設值為 no-referrer
。
透過設置 Strict-Transport-Security
來告訴瀏覽器強制使用 HTTPS 進行連線。可以參考 MDN 的說明文件 來了解各參數的意義。下方為使用 helmet 提供的方法來設置的範例:
app.use(
helmet.strictTransportSecurity({
maxAge: 123456,
})
);
參數預設值:
maxAge
:為 180 天
includeSubDomains
: 預設為 true
preload
:預設為 false
透過設置 X-Content-Type-Options
為 nosniff
來阻止瀏覽器對 Content-Type 不明的內容進行探查,以防止惡意程式碼的注入。可以參考 MDN 的說明文件。下方為使用 helmet 提供的方法來設置的範例:
app.use(helmet.noSniff());
透過設置 X-DNS-Prefetch-Control
來控制 DNS 的預讀取,以決定是否要用性能換取一些使用者的隱私。可以參考 MDN 的說明文件 。下方為使用 helmet 提供的方法來設置的範例:
app.use(
helmet.dnsPrefetchControl({
allow: true,
})
);
allow
預設為 false
。
透過設置 X-Download-Options
為 noopen
來指定 IE8 以上不要在下載框顯示「打開」選項。可以參考 微軟的說明文件。下方為使用 helmet 提供的方法來設置的範例:
app.use(helmet.ieNoOpen());
透過設置 X-Frame-Options
決定是否在瀏覽器中顯示 frame 或 iframe 指定的頁面,以減緩點擊劫持攻擊。可以參考 MDN 的說明文件。下方為使用 helmet 提供的方法來設置的範例:
helmet.frameguard({
action: "deny",
})
action
可填入的參數有:deny
、 sameorigin
,的預設值為 sameorigin
。
透過設置 X-Permitted-Cross-Domain-Policies
來決定你的網域政策加載跨域內容。可以參考 OWASP 的說明文件。下方為使用 helmet 提供的方法來設置的範例:
app.use(
helmet.permittedCrossDomainPolicies({
permittedPolicies: "by-content-type",
})
);
permittedPolicies
可填入的參數有:none
、 master-only
、 by-content-type
、 all
,預設值為 none
。
將 X-Powered-By
從 header 中移除,可以使攻擊者無法得知使用的工具為何,是 非常重要的配置 。下方為使用 helmet 提供的方法來設置的範例:
app.use(helmet.hidePoweredBy());
通過將 X-XSS-Protection
設為 0
,來關閉瀏覽器 XSS 過濾器。下方為使用 helmet 提供的方法來設置的範例:
app.use(helmet.xssFilter());
今天的內容有些艱澀,不過還是要大致了解 helmet 這個套件能夠做哪些事?又做了哪些事?才不會用了這個工具卻不知道這個工具是幹嘛的,另外,就算真的不想用它,也一定要將 X-Powered-By
移除!至少可以讓攻擊者不知道使用的框架、技術為何,增加攻擊的困難度。
由於本系列文的最終目標是用 MVC 架構來寫 Express,其中會使用到資料庫,所以下一篇會稍微介紹時下最夯的 NoSQL - MongoDB,好讓往後的文章有資料庫能完善應用。